/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package game;

import java.io.FileReader;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Vector;

/**
 *@author Gary Doyle, David Glasgow
 *
 *Class for representing the dictionary table, contains methods for generating anagrams and checking if words are valid according to the dictionary.
 */
public class DictionaryTable {

    EnglishScrabbleScorer myScorer = new EnglishScrabbleScorer();
    Scanner myScanner;
    Hashtable<String, String> ht = new Hashtable<String, String>();
    String value = "word";
    String line;
   
    /*
     * Constructor for the dictionaryTable.
     * @param the location of the dictionary file.
     */
    public DictionaryTable(String fileLoc) {
        try {
            myScanner = new Scanner(new FileReader(fileLoc)); //read in from file
                    
            while (myScanner.hasNextLine()) { //loop populates ht
                line = myScanner.nextLine();
                //changed 17/4 doesn't add words longer than 8, significantly improves performance 
                if(line.length()<9){
                	ht.put(line, value);
                }
            }
        } //print read in error
        catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
       }
    }

    /*
     * Check if the word is contained in the dictionary or not.
     * @param the word to be checked.
     */
    public boolean containsWord(String word) {
        String Key = word.toUpperCase(); //acount for not uppercase words
        return ht.containsKey(Key);
    }

    /*
     * Gets all the possible permutations of the string of the given length.
     * @param the string to get the permutations of, the length of the permutations.
     */
    public Vector<String> getAllWordsOfLength(int len, String letters) {
        StringBuffer useLetters = new StringBuffer(letters);
        StringBuffer makeWord = new StringBuffer();
        Vector<String> gather = new Vector<String>();
        gather = getAllWordsOfLength(len, useLetters, makeWord, gather);

        return gather;
    }

    public Vector<String> getAllWordsOfLength(int len, StringBuffer letters, StringBuffer word, Vector<String> gather) {

        //recursive anagram generator
        if (word.length() < len) {
            for (int i = 0; i < letters.length(); i++) {
                char chars = letters.charAt(i);
                letters.deleteCharAt(i);
                word.append(chars);
                gather = getAllWordsOfLength(len, letters, word, gather);
                letters.insert(i, chars);
                word.deleteCharAt(word.length() - 1);

            }
        } else {
            if (this.containsWord(word.toString())) {
                word.toString().intern();   //internalize word
                if (!gather.contains(word.toString())) {
                    gather.add(word.toString());
                }
            }
        }
        return gather;
    }

    /*
     * Gets the best word of length x from a given string.
     * @param the longest the word can be, the string to make the permutations of.
     */
    public String getBestWordIn(int maxLen, String letters) {

        int score = 0, maxScore = 0;
        String bestWord = "";

        for (int x = maxLen; x >= 2; x--) {//counting down should typically do less comparisons

            Vector<String> v = (getAllWordsOfLength(x, letters));

            Iterator<String> itr = v.iterator();
            //iterate through vector
            while (itr.hasNext()) {
                //score words and set best score
                String words = (itr.next().toString());
                score = myScorer.StringScore(words);
                if (score > maxScore) {
                    maxScore = score;
                    bestWord = words;
                }
                //at end of each vector, print out best word and it's score 
                if (!itr.hasNext()) {
                    //System.out.println("At end of vector number " + x + ", the best word was '" + bestWord + "' with a score of " + maxScore);
                }
            }
        }
        return bestWord;
    }
}
